/*******************************************************************************
 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
 * This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Marc R. Hoffmann - initial API and implementation
 *
 *******************************************************************************/
package org.jacoco.cli.internal;

import java.io.File;
import java.io.IOException;

import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.tools.ExecFileLoader;
import org.jacoco.report.DirectorySourceFileLocator;
import org.jacoco.report.FileMultiReportOutput;
import org.jacoco.report.IReportVisitor;
import org.jacoco.report.html.HTMLFormatter;
import org.jacoco.report.internal.html.AppInforDTO;

/**
 * 调试覆盖报告生成
 *
 * @author liaozhiyong
 */
public class CoverApiTestMain {

	/**
	 * clsss的类目录
	 */
	private File classesDirectory;
	/**
	 * 源码目录
	 */
	private File sourceDirectory;
	/**
	 * exec文件
	 */
	private File executionDataFile;

	/**
	 * 报告生成目录
	 */
	private File reportDirectory;
	/**
	 * old exec文件
	 */
	private File oldExecutionDataFile;
	/**
	 * old clsss的类目录
	 */
	private File oldClassesDirectory;


	public CoverApiTestMain(File classesDirectory, File sourceDirectory,
			File executionDataFile, File reportDirectory) {
		this.classesDirectory = classesDirectory;
		this.sourceDirectory = sourceDirectory;
		this.executionDataFile = executionDataFile;
		this.reportDirectory = reportDirectory;
	}

	public CoverApiTestMain(File classesDirectory, File sourceDirectory,
			File executionDataFile, File reportDirectory
			, File oldExecutionDataFile, File oldClassesDirectory) {
		this.classesDirectory = classesDirectory;
		this.sourceDirectory = sourceDirectory;
		this.executionDataFile = executionDataFile;
		this.reportDirectory = reportDirectory;
		this.oldExecutionDataFile = oldExecutionDataFile;
		this.oldClassesDirectory = oldClassesDirectory;
	}

	public static void main(String[] args) {
		try {
			/** dto for this report */
			AppInforDTO dto = new AppInforDTO();
			String projectDirectory = "D:\\workblue\\jacoco\\lib-231208\\jacoco-demo";
			// 目录下必须包含源码编译过的class文件,用来统计覆盖率。所以这里用server打出的jar包地址即可,运行的jar或者Class目录
			File classesDirectory = new File(projectDirectory,
					"target\\classes");
			File sourceDirectory = new File(projectDirectory,
					"src\\main\\java");
			// 覆盖率的exec文件地址
			File executionDataFile = new File(
					"D:\\workblue\\jacoco\\lib-231208\\demo.exec");
			// 要保存报告的地址
			File reportDirectory = new File(
					"D:\\workblue\\jacoco\\lib-231208\\debug\\", "coveragereport");
			
			CoverApiTestMain coverApiTest = new CoverApiTestMain(
					classesDirectory, sourceDirectory, executionDataFile,
					reportDirectory);
			// 解析exec
			ExecFileLoader execFileLoader = coverApiTest
					.loadExecutionData(executionDataFile);
			// 对比exec和class类，生成覆盖数据
			IBundleCoverage bundleCoverage = coverApiTest
					.analyzeStructure(execFileLoader);
			// 生成报告
			coverApiTest.createReport(bundleCoverage, execFileLoader, dto);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 第一步解析exec文件
	 *
	 * @throws IOException
	 */
	public ExecFileLoader loadExecutionData(File executionDataFile)
			throws IOException {
		// 解析exec
		ExecFileLoader execFileLoader = new ExecFileLoader();
		execFileLoader.load(executionDataFile);
		return execFileLoader;
	}

	public IBundleCoverage analyzeStructure(ExecFileLoader execFileLoader)
			throws IOException {

		// 增量覆盖
		// final CoverageBuilder coverageBuilder = new
		// CoverageBuilder("{method:"add"}");

		final CoverageBuilder coverageBuilder = new CoverageBuilder();
		final Analyzer analyzer = new Analyzer(
				execFileLoader.getExecutionDataStore(), coverageBuilder);

		analyzer.analyzeAll(this.classesDirectory);
		// new BundleCoverageImpl()
		return coverageBuilder.getBundle("报告率");
	}

	public void createReport(final IBundleCoverage bundleCoverage,
			ExecFileLoader execFileLoader, AppInforDTO dto) throws IOException {

		// Create a concrete report visitor based on some supplied
		// configuration. In this case we use the defaults
		final HTMLFormatter htmlFormatter = new HTMLFormatter();
		final IReportVisitor visitor = htmlFormatter
				.createVisitor(new FileMultiReportOutput(this.reportDirectory));

		// Initialize the report with all of the execution and session
		// information. At this point the report doesn't know about the
		// structure of the report being created
		visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(),
				execFileLoader.getExecutionDataStore().getContents());

		// Populate the report structure with the bundle coverage information.
		// Call visitGroup if you need groups in your report.
		visitor.visitBundle(bundleCoverage, new DirectorySourceFileLocator(
				this.sourceDirectory, "utf-8", 4), dto);

		visitor.visitEnd();

	}

}
